/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEBasicRenderLoop.cpp
// Author:		Gianluca Belardelli
// Date:		15/12/2014
//
/////////////////////////////////////////////////////////////////////////
#include <AEEngine.h>

//AEStaticGeometryInstanceCollection AEBasicRenderLoop::ms_gcGeometryInstanceCollection( 1024 );

AEBasicRenderLoop::AEBasicRenderLoop( void )
{
	m_bInitialized = 0;
	m_lpGeometryInstanceCollection = AENULL;
	InitRenderLoop();
}

AEBasicRenderLoop::~AEBasicRenderLoop( void )
{
	DeInitRenderLoop();
}

void AEBasicRenderLoop::InitRenderLoop( void )
{
	if( m_bInitialized )
		DeInitRenderLoop();

	m_uiFrameCounter = 0;
	m_bInitialized = AETRUE;

	m_lpGeometryInstanceCollection = new AEStaticGeometryInstanceCollection( 512 );
}

void AEBasicRenderLoop::DeInitRenderLoop( void )
{
	if( !m_bInitialized )
		return;
	
	m_bInitialized = AEFALSE;
}

void AEBasicRenderLoop::OnDoRenderLoop( void *lpUserData )
{
	m_uiFrameCounter++;

	AERenderContext *lpContext = AERenderContext::GetCurrentContext();
	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	AEMatrix4f matProj = lpContext->GetProjectionMatrix();
	AEMatrix4f matView = lpContext->GetCamera()->GetWorldToCameraTransformation();
	//AEMatrix4f matWorld;
	//matWorld.SetIdentity();

	AEMatrix4f matMVP;
	matMVP.SetMul( matView,  matProj );
	//matWorld.Mul( matMVP );

	GLint programID;
	glGetIntegerv (GL_CURRENT_PROGRAM,&programID );

	GLfloat fMatrix[16];

	matMVP.Get( fMatrix, AEML_RowMajor );
	GLuint MatrixID = glGetUniformLocation( programID, "MVP" );

	glUniformMatrix4fv( MatrixID, 1, GL_FALSE, (GLfloat *)&fMatrix );

	const AEINT32 nRenderFlags = lpContext->GetRenderFlags();
	if( !( nRenderFlags & AERENDERCONTEXTFLAG_NO_CLEARSCREEN ) )
	{
		AEngine::RenderLoopHelper.ClearScreen();
	}

	m_lpGeometryInstanceCollection->Clear();

	AESceneManagerI *lpMgr = AEngine::GetSceneManager();
	AEINT32 nZones = lpMgr->GetNumVisibilityZones();
	
	for( AEINT32 i=0; i<nZones; i++ )
	{
		AEVisibilityZone *lpZone = lpMgr->GetVisibilityZone(i);
		m_lpGeometryInstanceCollection->AppendCollection( *(lpZone->GetStaticGeometryInstances()) );
	}

	//glBindFramebuffer( GL_FRAMEBUFFER, ((AERenderableTexture *)lpContext->GetRenderTarget())->GetRenderTarget() );
	AEINT32 nGeometries = m_lpGeometryInstanceCollection->GetNumEntries();
	for( AEINT32 i=0; i<nGeometries; i++ )
	{
		AEStaticGeometryInstance *lpGeom = m_lpGeometryInstanceCollection->GetEntry( i );
		//lpGeom->
		lpGeom->Render();
	}

	//glBindFramebuffer(GL_FRAMEBUFFER, 0);
	#if defined(AE_PLATFORM_WIN32)
	SwapBuffers( GetDC( AEngine::GetDefaultVideoConfig()->GetSpecificPlatformInfo()->lpWindow->GetHandle() ) );
	#endif
}

